package com.mls.fivedistrict.server.impl;

import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.mls.fivedistrict.common.PageFilter;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.dao.UserMapper;
import com.mls.fivedistrict.entity.request.ChangePhoneRequest;
import com.mls.fivedistrict.entity.request.TransferAccountRequest;
import com.mls.fivedistrict.entity.request.UpdatePasswordRequest;
import com.mls.fivedistrict.entity.response.SecondInviteDetailResponse;
import com.mls.fivedistrict.entity.response.UserResponse;
import com.mls.fivedistrict.enums.*;
import com.mls.fivedistrict.event.WithdrawEvent;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.*;
import com.mls.fivedistrict.server.*;
import com.mls.fivedistrict.util.*;
import com.mls.fivedistrict.util.jedis.RedisPoolUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.xml.ws.Response;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static java.math.BigDecimal.ROUND_DOWN;

/**
 * Created by chenxiuxiang on 2018/3/15.
 */
@Slf4j
@Service("userService")
public class UserServiceImpl implements UserService {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Resource
    private ApplicationContext applicationContext;

    @Resource(name = "userMapper")
    UserMapper userMapper;
    @Value("#{settings['token.expirationTime']}")
    private Integer tokenExpirationTime;

    @Resource(name = "userInvitationService")
    UserInvitationService userInvitationService;
    @Resource(name = "commonService")
    CommonService commonService;
    @Resource(name = "calculateService")
    CalculateService calculateService;
    @Resource(name = "taskService")
    TaskService taskService;
    @Resource(name = "userTaskService")
    UserTaskService userTaskService;
    @Resource(name = "userService")
    UserService userService;
    @Resource(name = "propertyService")
    PropertyService propertyService;
    @Autowired
    private SendMessageUtil sendMessageUtil;
    @Resource(name = "integralService")
    IntegralService integralService;
    @Resource(name = "recordService")
    RecordService recordService;
    @Autowired
    GUserService gUserService;
    @Autowired
    UserVoteOptionService userVoteOptionService;

    @Autowired
    WithdrawRecordService withdrawRecordService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private TransferRecordService transferRecordService;


    @Transactional
    @Override
    public ServiceResponse addUser(User user, String invitationSourceCode) {
        Optional.ofNullable(user.getPhone()).orElseThrow(() -> new CustomerException("手机号不能为空"));
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andPhoneEqualTo(user.getPhone());
        long count = userMapper.countByExample(userExample);
        if (count > 0) {
            return ServiceResponse.createErrorResponse("手机号已存在");
        }
        if (StringUtils.isEmpty(user.getUsername())) {
            user.setUsername(user.getPhone());
        }
        int row = userMapper.insertSelective(user);
        if (row <= 0) {
            return ServiceResponse.createErrorResponse("添加失败");
        } else {
            //4-9注册赠送10个DWQ积分
            Task taskByCategory = taskService.getTaskByCategory(TaskCategoryEnum.REGISTER.getValue());
            if (taskByCategory != null && taskByCategory.getStatus().equals(TaskStatus.ENABLE.getValue())) {
                //如果注册任务存在 赠送积分
                taskService.completeTask(taskByCategory.getId(), user.getId(), "注册奖励");
            }


            if (!StringUtils.isEmpty(invitationSourceCode)) {
                UserExample userExampleInvitation = new UserExample();
                criteria = userExampleInvitation.createCriteria();
                criteria.andInvitationCodeEqualTo(invitationSourceCode);
                criteria.andIdNotEqualTo(user.getId());
                List<User> userList = userMapper.selectByExample(userExampleInvitation);
                if (userList.size() > 0) {
                    Long id = userList.get(0).getId();
                    User newUser = new User();
                    newUser.setId(user.getId());
                    newUser.setInviterUserId(id);
                    userMapper.updateByPrimaryKeySelective(newUser);
                    //更新邀请总数
//                    User invertUser = new User();
//                    invertUser.setId(id);
//                    invertUser.setInviterCount(userList.get(0).getInviterCount() + 1);
//                    userMapper.updateByPrimaryKeySelective(invertUser);
                    userMapper.updateUserInvite(id);
                }
            }

            String token = UUID.randomUUID().toString();
            User userDetail = userMapper.selectByPrimaryKey(user.getId());
            userDetail.setPassword(null);
            RedisPoolUtil.setEx(token, JsonUtils.objectToJson(userDetail), tokenExpirationTime * 24 * 60 * 60);
            return ServiceResponse.createSuccessResponse(token);
        }
    }

    @Override
    public ServiceResponse editUser(User user, Long userId) {
        if (userMapper.selectByPrimaryKey(userId) == null) {
            return ServiceResponse.createErrorResponse("用户不存在");
        }
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        if (!StringUtils.isEmpty(user.getPhone())) {
            criteria.andPhoneEqualTo(user.getPhone());
            criteria.andIdNotEqualTo(user.getId());
            long count = userMapper.countByExample(userExample);
            if (count > 0) {
                return ServiceResponse.createErrorResponse("手机号已存在");
            }
        }

        int row = userMapper.updateByPrimaryKeySelective(user);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse();
        } else {
            return ServiceResponse.createErrorResponse("更新失败");
        }

    }

    @Override
    public ServiceResponse getUserList(PageFilter pageFilter) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        Optional.ofNullable(pageFilter.getFilterMap().get("username")).map(username -> criteria.andUsernameLike("%" + username + "%"));
        Optional.ofNullable(pageFilter.getFilterMap().get("phone")).map(phone -> criteria.andPhoneLike("%" + phone + "%"));
        Optional.ofNullable(pageFilter.getFilterMap().get("createDate")).map(createDate -> criteria.andCreateDateGreaterThan(new Date(Long.parseLong(createDate))));
        Optional.ofNullable(pageFilter.getFilterMap().get("endDate")).map(endDate -> criteria.andCreateDateLessThan(new Date(Long.parseLong(endDate))));
        Optional.ofNullable(pageFilter.getFilterMap().get("isSubscribe")).map(isSubscribe -> criteria.andIsSubscribeEqualTo(Boolean.valueOf(isSubscribe)));
        Optional.ofNullable(pageFilter.getFilterMap().get("inviterUserId")).map(inviterUserId -> criteria.andInviterUserIdEqualTo(Long.valueOf(inviterUserId)));
        criteria.andIsDeleteEqualTo(false);
        if (!StringUtils.isEmpty(pageFilter.getOrderCause())) {
            userExample.setOrderByClause(pageFilter.getOrderCause());
        }
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<User> users = userMapper.selectByExample(userExample);
        PageInfo pageInfo = new PageInfo(users, 5);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @Transactional
    @Override
    public ServiceResponse getUser(String token) {
        String userInfo = RedisPoolUtil.get(token);
        User user = JsonUtils.jsonToPojo(userInfo, User.class);
        user = userMapper.selectByPrimaryKey(user.getId());
        if (user.getIsDelete()) {
            RedisPoolUtil.del(token);
            return ServiceResponse.createErrorResponse("账号已被注销");
        }
        boolean isFirtLogin = false;
        if (user.getLastActivityDate() == null || !TimeUtils.isToday(user.getLastActivityDate().getTime())) {
            user.setFirstLogin(true);
            User newUser = new User();
            newUser.setId(user.getId());
            newUser.setVersion(user.getVersion() + 1);
            newUser.setLastActivityDate(new Date());
            UserExample userExample = new UserExample();
            UserExample.Criteria criteria = userExample.createCriteria();
            criteria.andIdEqualTo(user.getId());
            criteria.andVersionEqualTo(user.getVersion());
            int i = userMapper.updateByExampleSelective(newUser, userExample);
            if (i != 0) {
                isFirtLogin = true;
                //代表今天是第一次登陆 增加算力
                Calculate calculate = new Calculate();
                calculate.setValue(2);
                calculate.setUserId(user.getId());
                calculate.setType(CalculateTypeEnum.PERPETUAL.getValue());
                calculate.setSource(CalculateSourceEnum.Login.getValue());
                calculate.setExpirationDate(user.getLastActivityDate());
                //8代表登录任务
                calculate.setTaskId(8L);
                calculateService.addCalculate(calculate);
                log.info("代表今天是第一次登陆 增加算力:{}", isFirtLogin);
            }

        }
        User newUser = userMapper.selectByPrimaryKey(user.getId());
        newUser.setFirstLogin(isFirtLogin);
        //1.判断用户是否有发放奖励的权限
        Wrapper wrapper = Condition.create().eq("user_id", user.getId());
        List<UserRole> roleList = userRoleService.selectList(wrapper);
        boolean hasPermission = false;
        if (roleList != null) {
            for (UserRole userRole : roleList) {
                List<RolePermission> rolePermissionList = userRole.getRole().getRolePermissionList();
                for (RolePermission rolePermission : rolePermissionList) {
                    RolePermissionDict rolePermissionDict = rolePermission.getRolePermissionDict();
                    if (rolePermissionDict.getCode().equals(PermissionCodeEnum.REWARD.getCode())) {
                        hasPermission = true;
                        break;
                    }
                }
            }
        }
        newUser.setHasReward(hasPermission);
        if (StringUtils.isEmpty(newUser.getRealname())) {
            newUser.setRealname(null);
        }


        UserResponse userResponse = JsonUtils.jsonToPojo(JsonUtils.objectToJson(newUser), UserResponse.class);
        if (!StringUtils.isEmpty(newUser.getWalletPassword())) {
            userResponse.setWalletPassword("has");
        }
        if (!StringUtils.isEmpty(newUser.getPassword())) {
            userResponse.setPassword("has");
        }
        RedisPoolUtil.setEx(token, JsonUtils.objectToJson(newUser), tokenExpirationTime * 24 * 60 * 60);
        return ServiceResponse.createSuccessResponse(userResponse);
    }

    @Override
    public ServiceResponse getUser(Long userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        return user == null ? ServiceResponse.createErrorResponse("用户不存在") : ServiceResponse.createSuccessResponse(user);
    }

    @UserOperate(moduleName = "用户", option = "用户登录")
    @Override
    public ServiceResponse loginByCaptcha(String phone) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andPhoneEqualTo(phone);
        List<User> users = userMapper.selectByExample(userExample);
        if (users.size() <= 0) {
            throw new CustomerException("用户不存在");
        }
        String token = UUID.randomUUID().toString();
        User user = users.get(0);
        if (user.getIsLock()) {
            return ServiceResponse.createErrorResponse("用户账号被锁，请联系客服人员");
        }
        if (!user.getIsEnable()) {
            return ServiceResponse.createErrorResponse("账号被禁用，请联系客服人员");
        }
        if (user.getIsDelete()) {
            return ServiceResponse.createErrorResponse("账号被注销");
        }
        user.setPassword(null);
        RedisPoolUtil.setEx(token, JsonUtils.objectToJson(user), tokenExpirationTime * 24 * 60 * 60);
        return ServiceResponse.createSuccessResponse(token);
    }

    @Transactional
    @Override
    public ServiceResponse subscribeUser(User user, String invitationSourceCode) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andPhoneEqualTo(user.getPhone());
        long count = userMapper.countByExample(userExample);
        if (count > 0) {
            return ServiceResponse.createErrorResponse("您已经参加过预约，请不要重复预约");
        }
        int insert = userMapper.insertSelective(user);
        if (insert > 0) {
            if (!StringUtils.isEmpty(invitationSourceCode)) {
                UserExample userExampleInvitation = new UserExample();
                UserExample.Criteria criteria = userExampleInvitation.createCriteria();
                criteria.andInvitationCodeEqualTo(invitationSourceCode);
                criteria.andIdNotEqualTo(user.getId());
                List<User> userList = userMapper.selectByExample(userExampleInvitation);
                if (userList.size() > 0) {
                    Long id = userList.get(0).getId();
                    user.setInviterUserId(id);
                    userMapper.updateByPrimaryKeySelective(user);
                    //更新邀请总数
                    User invertUser = new User();
                    invertUser.setId(id);
                    invertUser.setInviterCount(userList.get(0).getInviterCount() + 1);
                    userMapper.updateByPrimaryKeySelective(invertUser);
                }
            }
            //发送预约成功的验证码
            sendMessageUtil.sendMessage(user.getPhone(), user.getInvitationCode());
            return ServiceResponse.createSuccessResponse(user.getInvitationCode());
        } else {
            return ServiceResponse.createErrorResponse("预约失败");
        }
    }

    @Override
    public ServiceResponse deleteUser(Long userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if (user != null) {
            user = new User();
        } else {
            return ServiceResponse.createErrorResponse("用户不存在");
        }
        user.setIsDelete(true);
        userMapper.updateByPrimaryKeySelective(user);
        return null;
    }

    @Override
    public ServiceResponse calculateSum(Integer minParticipationCalculate) {

        Long normalSum = userMapper.normalCalculateSum(minParticipationCalculate);
        if (normalSum == null) {
            normalSum = 0L;
        }
        double sum = (normalSum);
        return ServiceResponse.createSuccessResponse(sum);
    }

    @Override
    public List<User> getUserListForTask(Map filter) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        if (filter.get("calculate") != null)
            criteria.andCalculateGreaterThanOrEqualTo(Integer.valueOf(filter.get("calculate") + ""));
        if (filter.get("startDate") != null)
            criteria.andCreateDateLessThanOrEqualTo(TimeUtils.millis2Date(Long.valueOf(filter.get("startDate") + "")));
        criteria.andIsDeleteEqualTo(false);
        criteria.andIsEnableEqualTo(true);
        List<User> users = userMapper.selectByExample(userExample);
        return users;
    }

    @Override
    public User getUserDetail(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public int editUser(User user) {
        int i = userMapper.updateByPrimaryKeySelective(user);
        return i;
    }

    @Override
    public User getUserByGD(Integer gUserId) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andGUserIdEqualTo(gUserId);
        List<User> users = userMapper.selectByExample(userExample);
        if (users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    @Override
    public ServiceResponse addCalculate(Calculate calculate, Long userId) {
        Date now = new Date();
        calculate.setCreateDate(now);
        calculate.setIsDelete(false);
        calculate.setUserId(userId);
        calculate.setSource(calculate.getSource());
        ServiceResponse response = calculateService.addCalculate(calculate);
        if (response.getState().equals(ResponseCode.ERROR)) {
            return response;
        }
//        User user = (User)getUser(userId).getData();
//        user.setCalculate(user.getCalculate()+calculate.getValue());
//        int row=editUser(user);
//        if(row<=0){
//            return ServiceResponse.createErrorResponse();
//        }
        return ServiceResponse.createSuccessResponse("算力增加成功!!");
    }


    @Override
    public List<User> getUserListNomal(PageFilter pageFilter) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        Optional.ofNullable(pageFilter.getFilterMap().get("username")).map(username -> criteria.andUsernameLike("%" + username + "%"));
        Optional.ofNullable(pageFilter.getFilterMap().get("phone")).map(phone -> criteria.andPhoneLike("%" + phone + "%"));
        Optional.ofNullable(pageFilter.getFilterMap().get("createDate")).map(createDate -> criteria.andCreateDateGreaterThan(new Date(Long.parseLong(createDate))));
        Optional.ofNullable(pageFilter.getFilterMap().get("endDate")).map(endDate -> criteria.andCreateDateLessThan(new Date(Long.parseLong(endDate))));
        Optional.ofNullable(pageFilter.getFilterMap().get("isSubscribe")).map(isSubscribe -> criteria.andIsSubscribeEqualTo(Boolean.valueOf(isSubscribe)));
        Optional.ofNullable(pageFilter.getFilterMap().get("inviterUserId")).map(inviterUserId -> criteria.andInviterUserIdEqualTo(Long.valueOf(inviterUserId)));
        criteria.andIsDeleteEqualTo(false);
        if (!StringUtils.isEmpty(pageFilter.getOrderCause())) {
            userExample.setOrderByClause(pageFilter.getOrderCause());
        }

        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<User> users = userMapper.selectByExampleForTask(userExample);
        return users;
    }

    @Override
    public ServiceResponse addPropertyForUser(Record record, Long userId) {
        //添加用户资产
        Long intergralId = record.getIntergralId();
        Property propertyDetailByIntegral = propertyService.getPropertyDetailByIntegral(intergralId, userId);
        //3-2 判断积分是否存在 增加总资产
        //3-2-1 增加记录
        if (propertyDetailByIntegral == null) {
            //代表第一次获得这种资产
            Property property = new Property();
            property.setIntegralId(intergralId);
            property.setTotal(record.getValue());
            property.setUserId(userId);
            propertyService.addProperty(property);
            record.setPropertyId(property.getId());
        } else {
            //代表资产存在继续累加
            Property property = new Property();
            property.setId(propertyDetailByIntegral.getId());
            property.setTotal(propertyDetailByIntegral.getTotal().add(record.getValue()).setScale(8, ROUND_DOWN));
            propertyService.editProperty(property);
            record.setPropertyId(property.getId());
        }
        record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
        //添加用户记录
        recordService.addRecord(record);
        //添加使用积分
        Integral integralDetail = integralService.getIntegralDetail(intergralId);
        Integral integral = new Integral();
        integral.setId(integralDetail.getId());
        integral.setUserIntegral(integralDetail.getUserIntegral().add(record.getValue()).setScale(8, ROUND_DOWN));
        integralService.editIntegral(integral);
        return ServiceResponse.createSuccessResponse();
    }

    @Override
    public ServiceResponse getInvitorsByUserId(Long inviterId, PageFilter pageFilter) {
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<UserAndAuth> userList = userMapper.selectInvitersUser(inviterId);
        PageInfo<UserAndAuth> pageInfo = new PageInfo<>(userList);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @Override
    public ServiceResponse search(PageFilter pageFilter) {
        Map<String, String> maps = pageFilter.getFilterMap();
        Map<String, Object> params = new HashMap<>();
        maps.forEach((k, v) -> {
            if (!StringUtil.isEmpty(v)) {
                if (k.equals("startDate") || k.equals("endDate")) {
                    params.put(k, TimeUtils.millis2Date(Long.parseLong(v)));
                } else {
                    params.put(k, v);
                }
            }
        });
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<UserAndAuth> userAndAuthList = userMapper.search(params);
        PageInfo pageInfo = new PageInfo(userAndAuthList);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @Override
    public User getUserByPhone(String phone) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andPhoneEqualTo(phone);
        List<User> userList = userMapper.selectByExample(userExample);
        if (userList != null && userList.size() >= 1) {
            return userList.get(0);
        }
        return null;
    }

    @Override
    public ServiceResponse getUserRecordList(PageFilter pageFilter) {
        ServiceResponse recordList = recordService.getRecordList(pageFilter);
        return recordList;
    }

    @Override
    public ServiceResponse getUserTotal() {
        UserExample userExample = new UserExample();
        long userTotal = userMapper.countByExample(userExample);
        return ServiceResponse.createSuccessResponse(userTotal);
    }

    @Override
    public ServiceResponse getUserBindSum() {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andGUserIdIsNotNull();
        long personSum = userMapper.countByExample(userExample);
        return ServiceResponse.createSuccessResponse(personSum);
    }

    @Override
    public ServiceResponse getCalculateSum() {
        long calculateSum = userMapper.getCalculateSum();
        return ServiceResponse.createSuccessResponse(calculateSum);
    }

    @Override
    public long getMaxId() {
        return userMapper.getMaxId();
    }

    @Transactional
    @Override
    public int extract(ExtractEntity extractEntity) {

        //0.校验积分是否可提现
        Integral integralDetail = integralService.getIntegralDetail(extractEntity.getIntegralId());
        if (integralDetail.getWithdrawStatus().equals("0")) {
            throw new CustomerException("积分不可提现");
        }
        if (integralDetail.getgIntegralId() == null) {
            throw new CustomerException("积分未绑定国盾");
        }

        //1.检验提现金额是否大于最小提现额度小于最大额度
//        BigDecimal minWithdrawNumber = integralDetail.getMinWithdrawNumber();
        BigDecimal minWithdrawNumber = new BigDecimal(100);
        Property propertyDetailByIntegral = propertyService.getPropertyDetailByIntegral(18L, extractEntity.getUserId());
        if (minWithdrawNumber.compareTo(propertyDetailByIntegral.getTotal()) > 0) {
            throw new CustomerException("您的DWQ数量不足最低要求：" + minWithdrawNumber.setScale(0) + "个");
        }

        String maxWithdrawNumber = integralDetail.getMaxWithdrawNumber();
        BigDecimal withdrawValue = extractEntity.getValue();
        int i1 = withdrawValue.compareTo(new BigDecimal("0.1"));
        log.info("i1:" + i1);
        if (withdrawValue.compareTo(new BigDecimal("0.1")) < 0) {
            throw new CustomerException("提取数量必须大于0.1");
        }
        if (withdrawValue.compareTo(new BigDecimal(maxWithdrawNumber)) > 0) {
            throw new CustomerException("提取数量不能大于" + maxWithdrawNumber);
        }

        //2.校验是否实名认证
        User userDetail = getUserDetail(extractEntity.getUserId());
        if (userDetail == null || StringUtil.isEmpty(userDetail.getRealname())) {
            throw new CustomerException("未进行实名认证");
        }
        if (integralDetail.getWithdrawStatus().equals("2")) {
            //代表只有创世居民可提现
            Boolean isSubscribe = userDetail.getIsSubscribe();
            if (!isSubscribe) {
                throw new CustomerException("只有创世居民可以提现");
            }
        }
        //3.校验是否绑定国盾账号
        if (userDetail.getgUserId() == null) {
            throw new CustomerException("未绑定国盾账号");
        }
        //4.校验和国盾真实姓名是否一致
        GUser gUserDetail = gUserService.getGUserDetail(extractEntity.getUserId());
        if (gUserDetail == null || !userDetail.getRealname().equals(gUserDetail.getgUserName())) {
            throw new CustomerException("和国盾身份信息不一致");
        }
        //5.校验钱包密码是否正确
        String wallet = Md5Utils.encryptPassword(extractEntity.getWalletPassword(), "walletPassword");
        if (!wallet.equals(userDetail.getWalletPassword())) {
            throw new CustomerException("钱包密码不正确");
        }
        //1.减去资产
        int i = propertyService.reducePropertyTotal(extractEntity.getUserId(), extractEntity.getIntegralId(), extractEntity.getValue());
        if (i <= 0) {
            //资产不足
            throw new CustomerException("资产不足");
        }
        //2.添加记录
        Record record = new Record();
        record.setIntergralId(extractEntity.getIntegralId());
        record.setUserId(extractEntity.getUserId());
        record.setSource("资产提取(提取中)");
        record.setValue(extractEntity.getValue().negate());
        record.setChangeReason("资产提取(提取中)");
        record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
        ServiceResponse serviceResponse = recordService.addRecord(record);
        if (!serviceResponse.getState().equals(ResponseCode.SUCCESS.getCode())) {
            //创建记录失败
            throw new CustomerException("创建记录失败");
        }
        //3.创建提取记录
        WithdrawRecord withdrawRecord = new WithdrawRecord();
        withdrawRecord.setUserId(extractEntity.getUserId());
        withdrawRecord.setgUserId(extractEntity.getgUserId());
        withdrawRecord.setIntegralId(extractEntity.getIntegralId());
        withdrawRecord.setIntegralName(integralDetail.getName());
        withdrawRecord.setPhone(userDetail.getPhone());
        withdrawRecord.setStatus(WithdrawStatusEnum.SUBMITTED.getValue());
        withdrawRecord.setSourceValue(extractEntity.getValue());
        withdrawRecord.setRecordId(record.getId());
        withdrawRecord.setgUserId(Long.valueOf(userDetail.getgUserId() + ""));
        withdrawRecord.setServiceCharge(integralDetail.getServiceCharge());
        withdrawRecord.setgIntegralId(integralDetail.getgIntegralId());
//        log.info("创建提现：{}", JsonUtils.objectToJson(withdrawRecord));
        int row = withdrawRecordService.addWithdrawRecord(withdrawRecord);
        if (row <= 0) {
            //创建提现记录失败
            throw new CustomerException("创建提取记录失败");
        }
        extractEntity.setgUserId(Long.valueOf(userDetail.getgUserId() + ""));
        extractEntity.setPhone(userDetail.getPhone());
        extractEntity.setServiceCharge(integralDetail.getServiceCharge());
        extractEntity.setRecordId(record.getId());
        extractEntity.setgIntegralId(integralDetail.getgIntegralId());
        extractEntity.setWithdrawRecordId(withdrawRecord.getId());

        String data = JsonUtils.objectToJson(extractEntity);
        applicationContext.publishEvent(new WithdrawEvent(this, data));
//        try {
//            rabbitTemplate.convertAndSend("extractExchange", "extractGD", data);
//        } catch (Exception e) {
//            log.error("消息入列失败");
////            throw new CustomerException("提交失败");
//
//        }
        return 1;

    }


    @Override
    public User getUserById(Long id) {
        return userMapper.getUserById(id);
    }

    @Override
    public ServiceResponse addIntegralForOtherUser(Long fromUserId, Long targetUserId, Long integralId, BigDecimal value) {
//        //判断用户是否可用真实
//        Property toProperty = propertyService.getPropertyDetailByIntegral(integralId, targetUserId);
//        if (toProperty == null) {
//            toProperty = new Property();
//            toProperty.setUserId(targetUserId);
//            toProperty.setIntegralId(integralId);
//            toProperty.setTotal(BigDecimal.ZERO);
//            ServiceResponse response = propertyService.insertProperty(toProperty);
//            if (!response.getState().equals(ResponseCode.SUCCESS.getCode())) {
//                return ServiceResponse.createErrorResponse("没有相关资产，并且创建失败");
//            }
//        }
//        Property fromProperty = propertyService.getPropertyDetailByIntegral(integralId, fromUserId);
//        if (fromProperty == null) {
////            fromProperty = new Property();
////            fromProperty.setUserId(record.getUserId());
////            fromProperty.setIntegralId(record.getIntergralId());
////            fromProperty.setTotal(BigDecimal.ZERO);
////            propertyService.insertProperty(fromProperty);
//            return ServiceResponse.createErrorResponse("用户资产为0");
//        }
//        if (fromProperty.getTotal().compareTo(value) < 0) {
//            return ServiceResponse.createErrorResponse("超出用户资产总量!");
//        }
//        ServiceResponse response = writeIntegralForOtherUser(fromProperty, toProperty, value);
        return null;
    }

    @Override
    public int updateUserPassword(UpdatePasswordRequest updatePasswordRequest) {
        User userDetail = getUserDetail(updatePasswordRequest.getUserId());
        if (!updatePasswordRequest.getCaptcha().equals(RedisPoolUtil.get(userDetail.getPhone()))) {
            throw new CustomerException("验证码不正确");
        }
        String userPassword = Md5Utils.encryptPassword(updatePasswordRequest.getNewPassword(), "userPassword");
        User user = new User();
        user.setId(updatePasswordRequest.getUserId());
        user.setPassword(userPassword);
        int i = userMapper.updateByPrimaryKeySelective(user);
        return i;
    }

    @Transactional
    @Override
    public int userTransferAccounts(TransferAccountRequest transferAccountRequest) {
        //0.判断是否需要实名认证
        Integral integralDetail = integralService.getIntegralDetail(transferAccountRequest.getIntegralId());
        Boolean transferIsRealname = integralDetail.getTransferIsRealname();
        if (transferIsRealname) {
            User userDetail = userService.getUserDetail(transferAccountRequest.getUserId());
            if (StringUtils.isEmpty(userDetail.getRealname())) {
                return -1;
            }
        }
        //1.判断是否有最小保留金额
        if (integralDetail.getRemainingValue().compareTo(new BigDecimal(0)) > 0) {
            Property propertyDetailByIntegral = propertyService.getPropertyDetailByIntegral(transferAccountRequest.getIntegralId(), transferAccountRequest.getUserId());
            BigDecimal total = propertyDetailByIntegral.getTotal();
            BigDecimal subtract = total.subtract(transferAccountRequest.getValue());
            if (subtract.compareTo(integralDetail.getRemainingValue()) <= 0) {
                throw new CustomerException("转账账号余额不得低于：" + integralDetail.getRemainingValue());
            }
        }

        transferAsset(transferAccountRequest, RecordProductTypeEnum.TRANSFER.getValue());
        return 1;
    }

    @Transactional
    @Override
    public int bonusIntegral(TransferAccountRequest transferAccountRequest) {
        transferAccountRequest.setIntegralId(18L);
        //1.判断用户是否有发放奖励的权限
        Wrapper wrapper = Condition.create().eq("user_id", transferAccountRequest.getUserId());
        List<UserRole> list = userRoleService.selectList(wrapper);
        if (list.size() <= 0) {
            throw new CustomerException("当前只有社区首领可以操作");
        }
        boolean hasPermission = false;
        for (UserRole userRole : list) {
            List<RolePermission> rolePermissionList = userRole.getRole().getRolePermissionList();
            for (RolePermission rolePermission : rolePermissionList) {
                RolePermissionDict rolePermissionDict = rolePermission.getRolePermissionDict();
                if (rolePermissionDict.getCode().equals(PermissionCodeEnum.REWARD.getCode())) {
                    hasPermission = true;
                    break;
                }
            }
        }
        if (!hasPermission) {
            throw new CustomerException("当前只有社区首领可以操作");
        }
        //2.判断积分是否可以用于奖励
        Integral integralDetail = integralService.getIntegralDetail(transferAccountRequest.getIntegralId());
        if (!integralDetail.getIsCanRewards()) {
            throw new CustomerException("积分暂时不支持奖励");
        }
        transferAsset(transferAccountRequest, RecordProductTypeEnum.COMMUNITYLEADERSREWARD.getValue());
        return 1;
    }

    @Override
    public int changeUserPhone(ChangePhoneRequest changePhoneRequest) {
        User userDetail = getUserDetail(changePhoneRequest.getUserId());
        String captcha = RedisPoolUtil.get(userDetail.getPhone());
        if (StringUtils.isEmpty(captcha) || !captcha.equals(changePhoneRequest.getOldCaptcha())) {
            throw new CustomerException("验证码错误");
        }
        String newCaptcha = RedisPoolUtil.get(changePhoneRequest.getNewPhone());
        if (StringUtils.isEmpty(newCaptcha) || !newCaptcha.equals(changePhoneRequest.getNewCaptcha())) {
            throw new CustomerException("新手机号验证码错误");
        }
        RedisPoolUtil.del(userDetail.getPhone());
        RedisPoolUtil.del(changePhoneRequest.getNewPhone());
        //1.检验新手机号在平台是否存在
        User userByPhone = getUserByPhone(changePhoneRequest.getNewPhone());
        if (userByPhone != null) {
            throw new CustomerException("新手机号已存在");
        }
        User user = new User();
        user.setId(changePhoneRequest.getUserId());
        user.setPhone(changePhoneRequest.getNewPhone());
        int i = editUser(user);
        if (i <= 0) {
            throw new CustomerException("操作失败");
        }
        return 1;
    }

    @Override
    public List<User> getInviteUserList(Long userId, PageFilter pageFilter) {
        Map<String, String> filterMap = pageFilter.getFilterMap();
        String order = pageFilter.getOrderCause();
        if (StringUtils.isEmpty(order)) {
            filterMap.put("order", "inviter_count desc");
        } else {
            filterMap.put("order", order);
        }
        String isReal = pageFilter.getFilterMap().get("isReal");
        List<User> users;
        if (!StringUtil.isEmpty(isReal)) {
            pageFilter.getFilterMap().put("userId", userId + "");
            if (isReal.equals("true")) {

                PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
                users = userMapper.selectUserForInviteReal(pageFilter.getFilterMap());
            } else {
                PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
                users = userMapper.selectUserForInviteNoReal(pageFilter.getFilterMap());
            }
        } else {
            String phone = pageFilter.getFilterMap().get("phone");
            UserExample userExample = new UserExample();
            UserExample.Criteria criteria = userExample.createCriteria();
            criteria.andInviterUserIdEqualTo(userId);
            userExample.setOrderByClause(filterMap.get("order"));
            if (phone == null) {
                PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
                users = userMapper.selectByExample(userExample);
            } else if (phone.equals("")) {
                users = new ArrayList<>();
            } else {
                criteria.andPhoneLike("%" + phone + "%");
                PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
                users = userMapper.selectByExample(userExample);
            }
        }


        return users;

    }

    @Override
    public long getCurrentMonthInviteUser(Long userId, PageFilter pageFilter) {
        String isReal = pageFilter.getFilterMap().get("isReal");
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andInviterUserIdEqualTo(userId);
        Date beginDayOfMonth = DateUtils.getBeginDayOfMonth();
        criteria.andCreateDateGreaterThanOrEqualTo(beginDayOfMonth);
        long emptyCount = 0;
        if (!StringUtils.isEmpty(isReal)) {
            if (isReal.equals("true")) {
                criteria.andRealnameNotEqualTo("");
                criteria.andRealnameIsNotNull();
            } else {
                criteria.andRealnameIsNull();
                UserExample emptyUserExample = new UserExample();
                UserExample.Criteria emptyUserCriteria = emptyUserExample.createCriteria();
                emptyUserCriteria.andRealnameEqualTo("");
                emptyUserCriteria.andInviterUserIdEqualTo(userId);
                emptyUserCriteria.andCreateDateGreaterThanOrEqualTo(beginDayOfMonth);
                emptyCount = userMapper.countByExample(emptyUserExample);
            }
        }
        long l = userMapper.countByExample(userExample);
        return l + emptyCount;
    }

    @Override
    public SecondInviteDetailResponse getSecondInviteDetail(Long userId) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andInviterUserIdEqualTo(userId);
        criteria.andRealnameIsNotNull();
        criteria.andRealnameNotEqualTo("");
        long realCount = userMapper.countByExample(userExample);
        UserExample countUserExample = new UserExample();
        UserExample.Criteria countCriteria = countUserExample.createCriteria();
        countCriteria.andInviterUserIdEqualTo(userId);
        long countCount = userMapper.countByExample(countUserExample);
        SecondInviteDetailResponse secondInviteDetailResponse = new SecondInviteDetailResponse();
        secondInviteDetailResponse.setCount(countCount);
        secondInviteDetailResponse.setHaveRealName(realCount);
        secondInviteDetailResponse.setNoRealName(countCount - realCount);
        UserExample monthUserExample = new UserExample();
        UserExample.Criteria monthCriteria = monthUserExample.createCriteria();
        monthCriteria.andInviterUserIdEqualTo(userId);
        Date beginDayOfMonth = DateUtils.getBeginDayOfMonth();
        monthCriteria.andCreateDateGreaterThanOrEqualTo(beginDayOfMonth);
        long monthCount = userMapper.countByExample(monthUserExample);
        secondInviteDetailResponse.setCurrentMonthTotal(monthCount);
        return secondInviteDetailResponse;
    }

    @Override
    public User getUserByUserName(String userName) {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andUsernameEqualTo(userName);
        List<User> users = userMapper.selectByExample(userExample);
        if (users.size() > 0) {
            return users.get(0);
        }
        return null;
    }

    @Override
    public int updateUser(User newUser, UserExample userExample) {
        int i = userMapper.updateByExampleSelective(newUser, userExample);
        return i;
    }

    @Override
    public String login(String userName, String password) {
        User userByUserName = userService.getUserByUserName(userName);
        if (userByUserName == null) {
            User userByPhone = userService.getUserByPhone(userName);
            if (userByPhone == null) {
                return null;
            } else {
                userByUserName = userByPhone;
            }
        }
        String sourcePassword = userByUserName.getPassword();
        String token = UUID.randomUUID().toString();
        String mdfPassword = Md5Utils.encryptPassword(password, "user");
        if (Md5Utils.encryptPassword(password, "user").equals(sourcePassword)) {
            userByUserName.setPassword(null);
            userByUserName.setWalletPassword(null);
            RedisPoolUtil.setEx(token, JsonUtils.objectToJson(userByUserName), tokenExpirationTime * 24 * 60 * 60);

            return token;
        }
        return null;
    }


    /**
     * 转移资产查询判断
     *
     * @param transferAccountRequest
     */
    @Override
    public void transferAsset(TransferAccountRequest transferAccountRequest, String recordSource) {
        User userDetail = getUserDetail(transferAccountRequest.getUserId());
        User targetUser = userMapper.selectByPrimaryKey(transferAccountRequest.getTargetUserId());
        if (targetUser == null) {
            throw new CustomerException("目标用户不存在");
        }
        if (userDetail.getId().equals(targetUser.getId())) {
            throw new CustomerException("不能对自己操作");
        }

        if (!transferAccountRequest.isRebate()) {
            String walletPassword = Md5Utils.encryptPassword(transferAccountRequest.getWalletPassword(), "walletPassword");
            if (!userDetail.getWalletPassword().equals(walletPassword)) {
                throw new CustomerException("支付密码错误");
            }
        }
        Integral integralDetail = integralService.getIntegralDetail(transferAccountRequest.getIntegralId());
        if (integralDetail == null) {
            throw new CustomerException("积分不存在");
        }
        Property propertyDetailByIntegral = propertyService.getPropertyDetailByIntegral(transferAccountRequest.getIntegralId(), transferAccountRequest.getUserId());
        if (propertyDetailByIntegral == null) {
            throw new CustomerException("资产不存在");
        }
        finalTransfer(transferAccountRequest, recordSource, targetUser, userDetail);
    }

    /**
     * 转移资产最后操作
     *
     * @param transferAccountRequest
     * @param recordSource
     * @param targetUser
     * @param userDetail
     */
    private void finalTransfer(TransferAccountRequest transferAccountRequest, String recordSource, User targetUser, User userDetail) {
        //1.减去个人资产
        int i = propertyService.reducePropertyTotal(transferAccountRequest.getUserId(), transferAccountRequest.getIntegralId(), transferAccountRequest.getValue());
        if (i <= 0) {
            throw new CustomerException("资产不足");
        }
        //1-1.添加转账记录
        Record record = new Record();
        if (recordSource.equals(RecordProductTypeEnum.COMMUNITYLEADERSREWARD.getValue())) {
            record.setChangeReason("奖励给" + targetUser.getPhone());
        } else if (recordSource.equals(RecordProductTypeEnum.TRANSFER.getValue())) {
            record.setChangeReason("转账给" + targetUser.getPhone());
        } else if (recordSource.equals(RecordProductTypeEnum.VOTE.getValue())) {
            record.setChangeReason(RecordProductTypeEnum.VOTE.getDesc());
        } else if (recordSource.equals(RecordProductTypeEnum.COMMODITYEXCHANGE.getValue())) {
            record.setChangeReason(RecordProductTypeEnum.COMMODITYEXCHANGE.getDesc());
        } else if (recordSource.equals(RecordProductTypeEnum.REBATE.getValue())) {
            record.setChangeReason(RecordProductTypeEnum.REBATE.getDesc());
        }
        record.setUserId(transferAccountRequest.getUserId());
        record.setSource(recordSource);
        record.setValue(transferAccountRequest.getValue().negate());
        record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
        record.setIntergralId(transferAccountRequest.getIntegralId());
        int insertRecordRow = recordService.insertRecord(record);
        if (insertRecordRow <= 0) {
            throw new CustomerException("记录创建失败");
        }
        //2.为用户增加资产
        //2-1 获取目标用户的资产
        Property targetUserProperty = propertyService.getPropertyDetailByIntegral(transferAccountRequest.getIntegralId(), transferAccountRequest.getTargetUserId());
        if (targetUserProperty == null) {
            //代表用户无此种资产
            Property property = new Property();
            property.setTotal(transferAccountRequest.getValue());
            property.setUserId(transferAccountRequest.getTargetUserId());
            property.setIntegralId(transferAccountRequest.getIntegralId());
            boolean b = propertyService.addProperty(property);
            if (!b) {
                throw new CustomerException("用户资产接收出错");
            }
        } else {
            //添加资产
            int addTargetPropertyRow = propertyService.increatementPropertyTotal(transferAccountRequest.getTargetUserId(), transferAccountRequest.getIntegralId(), transferAccountRequest.getValue());
            if (addTargetPropertyRow <= 0) {
                throw new CustomerException("转账出错");
            }
        }
        //添加记录
        Record targetRecord = new Record();
        if (recordSource.equals(RecordProductTypeEnum.COMMUNITYLEADERSREWARD.getValue())) {
            targetRecord.setChangeReason(userDetail.getPhone() + " 奖励");
        } else if (recordSource.equals(RecordProductTypeEnum.TRANSFER.getValue())) {
            targetRecord.setChangeReason(userDetail.getPhone() + " 转账");
        } else if (recordSource.equals(RecordProductTypeEnum.VOTE.getValue())) {
            targetRecord.setChangeReason(userDetail.getPhone() + " 投票");
        } else if (recordSource.equals(RecordProductTypeEnum.COMMODITYEXCHANGE.getValue())) {
            targetRecord.setChangeReason(userDetail.getPhone() + " 商品兑换");
        } else if (recordSource.equals(RecordProductTypeEnum.REBATE.getValue())) {
            targetRecord.setChangeReason(userDetail.getPhone() + " 返利");
        }
        targetRecord.setUserId(transferAccountRequest.getTargetUserId());
        targetRecord.setSource(recordSource);
        targetRecord.setValue(transferAccountRequest.getValue());
        targetRecord.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
        targetRecord.setIntergralId(transferAccountRequest.getIntegralId());
        int insertTargetRecordRow = recordService.insertRecord(targetRecord);
        if (insertTargetRecordRow <= 0) {
            throw new CustomerException("目标用户记录创建失败");
        }
        //添加转账记录
        TransferRecord transferRecord = new TransferRecord();
        transferRecord.setUserId(userDetail.getId());
        transferRecord.setTargetUserId(transferAccountRequest.getTargetUserId());
        transferRecord.setTransferRemind(transferAccountRequest.getRemind());
        transferRecord.setTransferValue(transferAccountRequest.getValue());

        transferRecord.setIntegralId(transferAccountRequest.getIntegralId());
        boolean insert = transferRecordService.insert(transferRecord);
        if (!insert) {
            throw new CustomerException("添加转账记录出错");
        }
    }

    @Override
    public boolean editUserRole(List<Role> roleList, Long userId) {
        boolean delete = userRoleService.delete(Condition.create().eq("user_id", userId));
        List<UserRole> userRoleList = new ArrayList<>();
        if (roleList == null || roleList.size() == 0) {
            return delete;
        }
        for (Role role : roleList) {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(role.getId());
            userRoleList.add(userRole);
        }
        boolean insert = userRoleService.insertBatch(userRoleList);
        if (!insert) {
            throw new CustomerException("更新出错");
        }
        return true;
    }

    @Override
    public List<UserVoteOption> getVoteUserList(PageFilter pageFilter) {
        pageFilter.getFilters().forEach(item -> {
            if (!StringUtils.isEmpty(item.getValue())) {
                if ("create_date".equalsIgnoreCase(item.getKey())) {
//                    item.setValue(TimeUtils.millis2Date(Long.parseLong(item.getValue().toString())).toString());
//                    item.setValue(item.getValue().toString().substring(0, 10));
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    item.setValue(simpleDateFormat.format(new Date(Long.parseLong(item.getValue().toString()))));
                } else if ("phone".equalsIgnoreCase(item.getKey())) {
                    User user = userService.getUserByPhone(item.getValue().toString());
                    item.setKey("user_id");
                    item.setOperator("eq");
                    item.setValue(user.getId().toString());
                }
            }
        });
        PageFilterUtils.recoWrapper(pageFilter);
        List<UserVoteOption> voteUserList = userVoteOptionService.selectListDetail(pageFilter.getWrapper());
        return voteUserList;
    }

    @Override
    public Long getTodayActivityPersonCount() {
        UserExample userExample = new UserExample();
        UserExample.Criteria criteria = userExample.createCriteria();
        criteria.andLastActivityDateBetween(DateUtils.getDayBegin(), DateUtils.getDayEnd());
        long count = userMapper.countByExample(userExample);
        return count;
    }
}
